home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / shwdib.zip / SHOWDIB.C < prev    next >
C/C++ Source or Header  |  1993-07-26  |  36KB  |  1,154 lines

  1. /*******************************************************************************
  2.  *                                                                             *
  3.  *  PROGRAM     : ShowDIB.c                                                    *
  4.  *                                                                             *
  5.  *  PURPOSE     : Application to illustrate the use of the GDI                 *
  6.  *                DIB (Device Independent Bitmap) and Palette manager          *
  7.  *                functions.                                                   *
  8.  *                                                                             *
  9.  *  FUNCTIONS   : WinMain ()             -  Creates the app. window and enters *
  10.  *                                          the message loop.                  *
  11.  *                                                                             *
  12.  *                WndProc()              -  Processes app. window messages.    *
  13.  *                                                                             *
  14.  *                MenuCommand()          -  Processes menu commands.           *
  15.  *                                                                             *
  16.  *                FreeDIB()              -  Frees currently active objects.    *
  17.  *                                                                             *
  18.  *                InitDIB()              -  Reads DIB from a file and loads it.*
  19.  *                                                                             *
  20.  *******************************************************************************/
  21. // COPYRIGHT:
  22. //
  23. //   (C) Copyright Microsoft Corp. 1992.  All rights reserved.
  24. //
  25. //   You have a royalty-free right to use, modify, reproduce and
  26. //   distribute the Sample Files (and/or any modified version) in
  27. //   any way you find useful, provided that you agree that
  28. //   Microsoft has no warranty obligations or liability for any
  29. //   Sample Application Files which are modified.
  30. #include <windows.h>
  31. #include <io.h>
  32. #include <stdio.h>
  33. #include "showdib.h"
  34. #include "commdlg.h"
  35.  
  36. DIBPARAMS DIBParams;                  /* params for the SETSCALING escape */
  37.  
  38. char achFileName[128] = "";
  39.  
  40. DWORD dwOffset;
  41.  
  42. NPLOGPALETTE pLogPal;
  43.  
  44. HPALETTE hpalSave = NULL;
  45.  
  46. HANDLE hInst;
  47.  
  48. RECT rcClip;
  49.  
  50. static HCURSOR hcurSave;
  51.  
  52. BOOL fPalColors = FALSE;          /* TRUE if the current DIB's color table   */
  53. /* contains palette indexes not rgb values */
  54.  
  55. WORD nAnimating = 0;              /* Palette animation count                 */
  56.  
  57. WORD UpdateCount = 0;
  58.  
  59. BOOL bMemoryDIB = FALSE; /* Load Entire DIB into memory in CF_DIB format */
  60.  
  61. BOOL bUpdateColors = TRUE;  /* Directly update screen colors                */
  62.  
  63. BOOL bDIBToDevice = FALSE; /* Use SetDIBitsToDevice() to BLT data.         */
  64.  
  65. BOOL bNoUgly = FALSE; /* Make window black on a WM_PALETTEISCHANGING  */
  66.  
  67. BOOL bLegitDraw = FALSE; /* We have a valid bitmap to draw               */
  68.  
  69. char szBitmapExt[] = "Bitmaps\0*.BMP; *.DIB; *.RLE\0";     /* possible file extensions */
  70.  
  71. WORD wTransparent = TRANSPARENT;               /* Mode of DC               */
  72.  
  73. char szAppName[] = "ShowDIB";                /* App. name                */
  74.  
  75. HPALETTE hpalCurrent = NULL;         /* Handle to current palette            */
  76.  
  77. HANDLE hdibCurrent = NULL;         /* Handle to current memory DIB         */
  78.  
  79. HBITMAP hbmCurrent = NULL;         /* Handle to current memory BITMAP      */
  80.  
  81. HANDLE hbiCurrent = NULL;         /* Handle to current bitmap info struct */
  82.  
  83. HWND hWndApp;                      /* Handle to app. window                */
  84.  
  85. /* Styles of app. window */
  86.  
  87. DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX |
  88. WS_MINIMIZEBOX | WS_THICKFRAME;
  89.  
  90.  
  91. void PrintDIB (HWND hWnd, HDC hDC, int x, int y, int dx, int dy);
  92. /****************************************************************************
  93.  *                                                                          *
  94.  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                        *
  95.  *                                                                          *
  96.  *  PURPOSE    : Creates the app. window and enters the message loop.       *
  97.  *                                                                          *
  98.  ****************************************************************************/
  99.  
  100.  
  101. int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  102. HANDLE hInstance, hPrevInstance;
  103. LPSTR lpszCmdLine;
  104. int nCmdShow;
  105. {
  106.    HWND hWnd;
  107.    WNDCLASS wndclass;
  108.    MSG msg;
  109.    short xScreen, yScreen;
  110.    char ach[40];
  111.    DWORD dwWinFlags;
  112.  
  113.    hInst = hInstance;
  114.  
  115.    /* default to MEMORY DIB's if XWindows */
  116.    dwWinFlags = GetWinFlags();
  117.    bMemoryDIB = (BOOL)(dwWinFlags & WF_PMODE);
  118.  
  119.    /* Initialize clip rectangle */
  120.    SetRectEmpty(&rcClip);
  121.    if (!hPrevInstance)
  122.    {
  123.       wndclass.style = CS_DBLCLKS;
  124.       wndclass.lpfnWndProc = WndProc;
  125.       wndclass.cbClsExtra = 0;
  126.       wndclass.cbWndExtra = 0;
  127.       wndclass.hInstance = hInstance;
  128.       wndclass.hIcon = LoadIcon(hInst, "SHOWICON");
  129.       wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  130.       wndclass.hbrBackground = COLOR_WINDOW + 1;
  131.       wndclass.lpszMenuName = szAppName;
  132.       wndclass.lpszClassName = szAppName;
  133.       if (!RegisterClass(&wndclass))
  134.          return FALSE;
  135.    }
  136.    if (!GetProfileString("extensions", "bmp", "", ach, sizeof(ach)))
  137.       WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp");
  138.    if (!GetProfileString("extensions", "dib", "", ach, sizeof(ach)))
  139.       WriteProfileString("extensions", "dib", "showdib.exe ^.dib");
  140.  
  141.    /* Save the pointer to the command line */
  142.    lstrcpy(achFileName, lpszCmdLine);
  143.    xScreen = GetSystemMetrics(SM_CXSCREEN);
  144.    yScreen = GetSystemMetrics(SM_CYSCREEN);
  145.  
  146.    /* Create the app. window */
  147.    hWnd = CreateWindow(szAppName, szAppName, dwStyle, CW_USEDEFAULT, 0, xScreen
  148.                        / 2, yScreen / 2, NULL, NULL, hInstance, NULL);
  149.    ShowWindow(hWndApp = hWnd, nCmdShow);
  150.  
  151.    /* Enter message loop */
  152.    while (GetMessage(&msg, NULL, 0, 0))
  153.    {
  154.       TranslateMessage(&msg);
  155.       DispatchMessage(&msg);
  156.    }
  157.    return msg.wParam;
  158. }
  159.  
  160. /****************************************************************************
  161.  *                                                                          *
  162.  *  FUNCTION   : WndProc (hWnd, iMessage, wParam, lParam)                   *
  163.  *                                                                          *
  164.  *  PURPOSE    : Processes window messages.                                 *
  165.  *                                                                          *
  166.  ****************************************************************************/
  167.  
  168.  
  169. long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  170. HWND hWnd;
  171. UINT iMessage;
  172. WPARAM wParam;
  173. LPARAM lParam;
  174. {
  175.    PAINTSTRUCT ps;
  176.    HDC hDC;
  177.    HANDLE h;
  178.    WORD i;
  179.    int iMax;
  180.    int iMin;
  181.    int iPos;
  182.    int dn;
  183.    RECT rc, Rect;
  184.    HPALETTE hOldPal;
  185.  
  186.    switch (iMessage)
  187.       {
  188.    case WM_DESTROY:
  189.       /* Clean up and quit */
  190.       FreeDib();
  191.       PostQuitMessage(0);
  192.       break;
  193.  
  194.    case WM_CREATE:
  195.       /* Allocate space for our logical palette */
  196.       pLogPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, (sizeof(LOGPALETTE) + (
  197.                                          sizeof(PALETTEENTRY) * (MAXPALETTE))))
  198.    ;
  199.  
  200.       /* If DIB initialization fails, quit */
  201.       if (achFileName[0] && !InitDIB(hWnd))
  202.          PostQuitMessage(3);
  203.  
  204.    /* fall through */
  205.  
  206.    case WM_PALETTEISCHANGING:
  207.       /* if SHOWDIB was not responsible for palette change and if
  208.        * ok to hide changes, paint app. window black.
  209.        */
  210.       if (wParam != hWnd && bNoUgly)
  211.       {
  212.          GetClientRect(hWnd, &Rect);
  213.          hDC = GetDC(hWnd);
  214.          FillRect(hDC, (LPRECT)&Rect, GetStockObject(BLACK_BRUSH));
  215.          ReleaseDC(hWnd, hDC);
  216.       }
  217.       break;
  218.  
  219.    case WM_ACTIVATE:
  220.       if (!wParam)  /* app. is being de-activated */
  221.          break;
  222.    /* If the app. is moving to the foreground, fall through and
  223.     * redraw full client area with the newly realized palette,
  224.     * if the palette has changed.
  225.     */
  226.  
  227.    case WM_QUERYNEWPALETTE:
  228.       /* If palette realization causes a palette change,
  229.        * we need to do a full redraw.
  230.        */
  231.       if (bLegitDraw)
  232.       {
  233.          hDC = GetDC(hWnd);
  234.          hOldPal = SelectPalette(hDC, hpalCurrent, 0);
  235.          i = RealizePalette(hDC);
  236.          SelectPalette(hDC, hOldPal, 0);
  237.          ReleaseDC(hWnd, hDC);
  238.          if (i)
  239.          {
  240.             InvalidateRect(hWnd, (LPRECT)(NULL), 1);
  241.             UpdateCount = 0;
  242.             return 1;
  243.          }
  244.          else
  245.             return FALSE;
  246.       }
  247.       else
  248.          return FALSE;
  249.       break;
  250.  
  251.    case WM_PALETTECHANGED:
  252.       /* if SHOWDIB was not responsible for palette change and if
  253.        * palette realization causes a palette change, do a redraw.
  254.        */
  255.       if (wParam != hWnd)
  256.       {
  257.          if (bLegitDraw)
  258.          {
  259.             hDC = GetDC(hWnd);
  260.             hOldPal = SelectPalette(hDC, hpalCurrent, 0);
  261.             i = RealizePalette(hDC);
  262.             if (i)
  263.             {
  264.                if (bUpdateColors)
  265.                {
  266.                   UpdateColors(hDC);
  267.                   UpdateCount++;
  268.                }
  269.                else
  270.                   InvalidateRect(hWnd, (LPRECT)(NULL), 1);
  271.             }
  272.             SelectPalette(hDC, hOldPal, 0);
  273.             ReleaseDC(hWnd, hDC);
  274.          }
  275.       }
  276.       break;
  277.  
  278.    case WM_RENDERALLFORMATS:
  279.       /* Ensure that clipboard data can be rendered even tho'
  280.        * app. is being destroyed.
  281.        */
  282.       SendMessage(hWnd, WM_RENDERFORMAT, CF_DIB, 0L);
  283.       SendMessage(hWnd, WM_RENDERFORMAT, CF_BITMAP, 0L);
  284.       SendMessage(hWnd, WM_RENDERFORMAT, CF_PALETTE, 0L);
  285.       break;
  286.  
  287.    case WM_RENDERFORMAT:
  288.       /* Format data in manner specified and pass the data
  289.        * handle to clipboard.
  290.        */
  291.       if (h = RenderFormat(wParam))
  292.          SetClipboardData(wParam, h);
  293.       break;
  294.  
  295.    case WM_COMMAND:
  296.       /* Process menu commands */
  297.       return MenuCommand(hWnd, wParam);
  298.       break;
  299.  
  300.    case WM_TIMER:
  301.       /* Signal for palette animation */
  302.       hDC = GetDC(hWnd);
  303.       hOldPal = SelectPalette(hDC, hpalCurrent, 0);
  304.       {
  305.          PALETTEENTRY peTemp;
  306.  
  307.          /* Shift all palette entries left by one position and wrap
  308.           * around the first entry
  309.           */
  310.  
  311.          peTemp = pLogPal->palPalEntry[0];
  312.          for (i = 0; i < (pLogPal->palNumEntries - 1); i++)
  313.             pLogPal->palPalEntry[i] = pLogPal->palPalEntry[i + 1];
  314.          pLogPal->palPalEntry[i] = peTemp;
  315.       }
  316.       /* Replace entries in logical palette with new entries*/
  317.       AnimatePalette(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->
  318.                      palPalEntry);
  319.       SelectPalette(hDC, hOldPal, 0);
  320.       ReleaseDC(hWnd, hDC);
  321.  
  322.       /* Decrement animation count and terminate animation
  323.        * if it reaches zero
  324.        */
  325.       if (!(--nAnimating))
  326.          PostMessage(hWnd, WM_COMMAND, IDM_ANIMATE0, 0L);
  327.       break;
  328.  
  329.    case WM_PAINT:
  330.       /* If we have updated more than once, the rest of our
  331.        * window is not in some level of degradation worse than
  332.        * our redraw...  we need to redraw the whole area
  333.        */
  334.       if (UpdateCount > 1)
  335.       {
  336.          BeginPaint(hWnd, &ps);
  337.          EndPaint(hWnd, &ps);
  338.          UpdateCount = 0;
  339.          InvalidateRect(hWnd, (LPRECT)(NULL), 1);
  340.          break;
  341.       }
  342.       hDC = BeginPaint(hWnd, &ps);
  343.       AppPaint(hWnd, hDC, GetScrollPos(hWnd, SB_HORZ), GetScrollPos(hWnd,
  344.                SB_VERT));
  345.       EndPaint(hWnd, &ps);
  346.       break;
  347.  
  348.    case WM_SIZE:
  349.       SetScrollRanges(hWnd);
  350.       break;
  351.  
  352.    case WM_KEYDOWN:
  353.       /* Translate keyboard messages to scroll commands */
  354.       switch (wParam)
  355.          {
  356.       case VK_UP:
  357.          PostMessage(hWnd, WM_VSCROLL, SB_LINEUP, 0L);
  358.          break;
  359.  
  360.       case VK_DOWN:
  361.          PostMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, 0L);
  362.          break;
  363.  
  364.       case VK_PRIOR:
  365.          PostMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0L);
  366.          break;
  367.  
  368.       case VK_NEXT:
  369.          PostMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
  370.          break;
  371.  
  372.       case VK_HOME:
  373.          PostMessage(hWnd, WM_HSCROLL, SB_PAGEUP, 0L);
  374.          break;
  375.  
  376.       case VK_END:
  377.          PostMessage(hWnd, WM_HSCROLL, SB_PAGEDOWN, 0L);
  378.          break;
  379.  
  380.       case VK_LEFT:
  381.          PostMessage(hWnd, WM_HSCROLL, SB_LINEUP, 0L);
  382.          break;
  383.  
  384.       case VK_RIGHT:
  385.          PostMessage(hWnd, WM_HSCROLL, SB_LINEDOWN, 0L);
  386.          break;
  387.          }
  388.       break;
  389.  
  390.    case WM_KEYUP:
  391.       switch (wParam)
  392.          {
  393.       case VK_UP:
  394.  
  395.       case VK_DOWN:
  396.  
  397.       case VK_PRIOR:
  398.  
  399.       case VK_NEXT:
  400.          PostMessage(hWnd, WM_VSCROLL, SB_ENDSCROLL, 0L);
  401.          break;
  402.  
  403.       case VK_HOME:
  404.  
  405.       case VK_END:
  406.  
  407.       case VK_LEFT:
  408.  
  409.       case VK_RIGHT:
  410.          PostMessage(hWnd, WM_HSCROLL, SB_ENDSCROLL, 0L);
  411.          break;
  412.          }
  413.       break;
  414.  
  415.    case WM_VSCROLL:
  416.       /* Calculate new vertical scroll position */
  417.       GetScrollRange(hWnd, SB_VERT, &iMin, &iMax);
  418.       iPos = GetScrollPos(hWnd, SB_VERT);
  419.       GetClientRect(hWnd, &rc);
  420.       switch (wParam)
  421.          {
  422.       case SB_LINEDOWN:
  423.          dn = rc.bottom / 16 + 1;
  424.          break;
  425.  
  426.       case SB_LINEUP:
  427.          dn = -rc.bottom / 16 + 1;
  428.          break;
  429.  
  430.       case SB_PAGEDOWN:
  431.          dn = rc.bottom / 2 + 1;
  432.          break;
  433.  
  434.       case SB_PAGEUP:
  435.          dn = -rc.bottom / 2 + 1;
  436.          break;
  437.  
  438.       case SB_THUMBTRACK:
  439.  
  440.       case SB_THUMBPOSITION:
  441.          dn = LOWORD(lParam) - iPos;
  442.          break;
  443.  
  444.       default:
  445.          dn = 0;
  446.          }
  447.       /* Limit scrolling to current scroll range */
  448.       if (dn = BOUND (iPos + dn, iMin, iMax) - iPos)
  449.       {
  450.          ScrollWindow(hWnd, 0, -dn, NULL, NULL);
  451.          SetScrollPos(hWnd, SB_VERT, iPos + dn, TRUE);
  452.       }
  453.       break;
  454.  
  455.    case WM_HSCROLL:
  456.       /* Calculate new horizontal scroll position */
  457.       GetScrollRange(hWnd, SB_HORZ, &iMin, &iMax);
  458.       iPos = GetScrollPos(hWnd, SB_HORZ);
  459.       GetClientRect(hWnd, &rc);
  460.       switch (wParam)
  461.          {
  462.       case SB_LINEDOWN:
  463.          dn = rc.right / 16 + 1;
  464.          break;
  465.  
  466.       case SB_LINEUP:
  467.          dn = -rc.right / 16 + 1;
  468.          break;
  469.  
  470.       case SB_PAGEDOWN:
  471.          dn = rc.right / 2 + 1;
  472.          break;
  473.  
  474.       case SB_PAGEUP:
  475.          dn = -rc.right / 2 + 1;
  476.          break;
  477.  
  478.       case SB_THUMBTRACK:
  479.  
  480.       case SB_THUMBPOSITION:
  481.          dn = LOWORD (lParam) - iPos;
  482.          break;
  483.  
  484.       default:
  485.          dn = 0;
  486.          }
  487.       /* Limit scrolling to current scroll range */
  488.       if (dn = BOUND (iPos + dn, iMin, iMax) - iPos)
  489.       {
  490.          ScrollWindow(hWnd, -dn, 0, NULL, NULL);
  491.          SetScrollPos(hWnd, SB_HORZ, iPos + dn, TRUE);
  492.       }
  493.       break;
  494.  
  495.    case WM_LBUTTONDOWN:
  496.       /* Start rubberbanding a rect. and track it's dimensions.
  497.        * set the clip rectangle to it's dimensions.
  498.        */
  499.       TrackMouse(hWnd, MAKEPOINT (lParam));
  500.       break;
  501.  
  502.    case WM_LBUTTONDBLCLK:
  503.       break;
  504.  
  505.    case WM_INITMENU:
  506.       /* check/uncheck menu items depending on state  of related
  507.        * flags
  508.        */
  509.       CheckMenuItem(wParam, IDM_UPDATECOL, (bUpdateColors ? MF_CHECKED :
  510.                     MF_UNCHECKED));
  511.       CheckMenuItem(wParam, IDM_TRANSPARENT, (wTransparent == TRANSPARENT ?
  512.                     MF_CHECKED : MF_UNCHECKED));
  513.       CheckMenuItem(wParam, IDM_DIBSCREEN, (bDIBToDevice ? MF_CHECKED :
  514.                     MF_UNCHECKED));
  515.       CheckMenuItem(wParam, IDM_NOUGLY, (bNoUgly ? MF_CHECKED : MF_UNCHECKED));
  516.       CheckMenuItem(wParam, IDM_MEMORYDIB, (bMemoryDIB ? MF_CHECKED :
  517.                     MF_UNCHECKED));
  518.       EnableMenuItem(wParam, IDM_PASTEDIB, IsClipboardFormatAvailable(CF_DIB) ?
  519.                      MF_ENABLED : MF_GRAYED);
  520.       EnableMenuItem(wParam, IDM_PASTEDDB, IsClipboardFormatAvailable(CF_BITMAP
  521.                      ) ? MF_ENABLED : MF_GRAYED);
  522.       EnableMenuItem(wParam, IDM_PASTEPAL, IsClipboardFormatAvailable(
  523.                      CF_PALETTE) ? MF_ENABLED : MF_GRAYED);
  524.       EnableMenuItem(wParam, IDM_PRINT, bLegitDraw ? MF_ENABLED : MF_GRAYED);
  525.       EnableMenuItem(wParam, IDM_SAVE, bLegitDraw ? MF_ENABLED : MF_GRAYED);
  526.       EnableMenuItem(wParam, IDM_COPY, bLegitDraw ? MF_ENABLED : MF_GRAYED);
  527.       EnableMenuItem(wParam, IDM_ANIMATE0, bLegitDraw ? MF_ENABLED : MF_GRAYED)
  528.    ;
  529.       EnableMenuItem(wParam, IDM_ANIMATE5, bLegitDraw ? MF_ENABLED : MF_GRAYED)
  530.    ;
  531.       EnableMenuItem(wParam, IDM_ANIMATE50, bLegitDraw ? MF_ENABLED : MF_GRAYED
  532.                      );
  533.       EnableMenuItem(wParam, IDM_ANIMATE100, bLegitDraw ? MF_ENABLED :
  534.                      MF_GRAYED);
  535.       EnableMenuItem(wParam, IDM_ANIMATE200, bLegitDraw ? MF_ENABLED :
  536.                      MF_GRAYED);
  537.       EnableMenuItem(wParam, IDM_ANIMATE201, bLegitDraw ? MF_ENABLED :
  538.                      MF_GRAYED);
  539.       EnableMenuItem(wParam, IDM_STEALCOL, bLegitDraw ? MF_ENABLED : MF_GRAYED)
  540.    ;
  541.       break;
  542.  
  543.    default:
  544.       return DefWindowProc(hWnd, iMessage, wParam, lParam);
  545.       }
  546.    return 0L;
  547. }
  548. /****************************************************************************
  549.  *                                                                          *
  550.  *  FUNCTION   : MenuCommand ( HWND hWnd, WORD wParam)                      *
  551.  *                                                                          *
  552.  *  PURPOSE    : Processes menu commands.                                   *
  553.  *                                                                          *
  554.  *  RETURNS    : TRUE  - if command could be processed.                     *
  555.  *               FALSE - otherwise                                          *
  556.  *                                                                          *
  557.  ****************************************************************************/
  558.  
  559.  
  560. BOOL MenuCommand (hWnd, id)
  561. HWND hWnd;
  562. WORD id;
  563. {
  564.    BITMAPINFOHEADER bi;
  565.    HDC hDC;
  566.    HANDLE h;
  567.    HBITMAP hbm;
  568.    HPALETTE hpal;
  569.    WORD i;
  570.    char Name[40];
  571.    BOOL bSave;
  572.    int xSize, ySize, xRes, yRes, dx, dy;
  573.    RECT Rect;
  574.    int fh;
  575.    WORD fFileOptions;
  576.    OPENFILENAME ofn;
  577.  
  578.    switch (id)
  579.       {
  580.    case IDM_ABOUT:
  581.       /* Show About .. box */
  582.       fDialog(ABOUTBOX, hWnd, AppAbout);
  583.       break;
  584.  
  585.    case IDM_COPY:
  586.       if (!bLegitDraw)
  587.          return 0L;
  588.  
  589.       /* Clean clipboard of contents */
  590.       if (OpenClipboard(hWnd))
  591.       {
  592.          EmptyClipboard();
  593.          SetClipboardData(CF_DIB, NULL);
  594.          SetClipboardData(CF_BITMAP, NULL);
  595.          SetClipboardData(CF_PALETTE, NULL);
  596.          CloseClipboard();
  597.       }
  598.       break;
  599.  
  600.    case IDM_PASTEPAL:
  601.       if (OpenClipboard(hWnd))
  602.       {
  603.          if (h = GetClipboardData(CF_PALETTE))
  604.          {
  605.             /* Delete current palette and get the CF_PALETTE data
  606.              * from the clipboard
  607.              */
  608.             if (hpalCurrent)
  609.                DeleteObject(hpalCurrent);
  610.             hpalCurrent = CopyPalette(h);
  611.  
  612.             /*
  613.              * If we have a bitmap realized against the old palette
  614.              * delete the bitmap and rebuild it using the new palette.
  615.              */
  616.             if (hbmCurrent)
  617.             {
  618.                DeleteObject(hbmCurrent);
  619.                hbmCurrent = NULL;
  620.                if (hdibCurrent)
  621.                   hbmCurrent = BitmapFromDib(hdibCurrent, hpalCurrent);
  622.             }
  623.          }
  624.          CloseClipboard();
  625.       }
  626.       break;
  627.  
  628.    case IDM_PASTEDIB:
  629.       if (OpenClipboard(hWnd))
  630.       {
  631.          if (h = GetClipboardData(CF_DIB))
  632.          {
  633.             /* Delete current DIB and get CF_DIB and
  634.              * CF_PALETTE format data from the clipboard
  635.              */
  636.             hpal = GetClipboardData(CF_PALETTE);
  637.             FreeDib();
  638.             hdibCurrent = CopyHandle(h);
  639.             if (hdibCurrent)
  640.             {
  641.                bLegitDraw = TRUE;
  642.                lstrcpy(achFileName, "<Clipboard>");
  643.                hbiCurrent = hdibCurrent;
  644.  
  645.                /* If there is a CF_PALETTE object in the
  646.                 * clipboard, this is the palette to assume
  647.                 * the DIB should be realized against, otherwise
  648.                 * create a palette for it.
  649.                 */
  650.                if (hpal)
  651.                   hpalCurrent = CopyPalette(hpal);
  652.                else
  653.                   hpalCurrent = CreateDibPalette(hdibCurrent);
  654.                SizeWindow(hWnd);
  655.             }
  656.             else
  657.             {
  658.                bLegitDraw = FALSE;
  659.                ErrMsg("No Memory Available!");
  660.             }
  661.          }
  662.          CloseClipboard();
  663.       }
  664.       break;
  665.  
  666.    case IDM_PASTEDDB:
  667.       if (OpenClipboard(hWnd))
  668.       {
  669.          if (hbm = GetClipboardData(CF_BITMAP))
  670.          {
  671.             hpal = GetClipboardData(CF_PALETTE);
  672.             FreeDib();
  673.  
  674.             /*
  675.              * If there is a CF_PALETTE object in the
  676.              * clipboard, this is the palette to assume
  677.              * the bitmap is realized against.
  678.              */
  679.             if (hpal)
  680.                hpalCurrent = CopyPalette(hpal);
  681.             else
  682.                hpalCurrent = GetStockObject(DEFAULT_PALETTE);
  683.             hdibCurrent = DibFromBitmap(hbm, BI_RGB, 0, hpalCurrent);
  684.             if (hdibCurrent)
  685.             {
  686.                bLegitDraw = TRUE;
  687.                lstrcpy(achFileName, "<Clipboard>");
  688.                hbiCurrent = hdibCurrent;
  689.                if (bMemoryDIB)
  690.                   hbmCurrent = BitmapFromDib(hdibCurrent, hpalCurrent);
  691.                SizeWindow(hWnd);
  692.             }
  693.             else
  694.             {
  695.                bLegitDraw = FALSE;
  696.                ErrMsg("No Memory Available!");
  697.             }
  698.          }
  699.          CloseClipboard();
  700.       }
  701.       break;
  702.  
  703.    case IDM_PRINT:
  704.       GetWindowText(hWnd, Name, sizeof(Name));
  705.       DibInfo(hbiCurrent, &bi);
  706.       if (!IsRectEmpty(&rcClip))
  707.       {
  708.          bi.biWidth = rcClip.right - rcClip.left;
  709.          bi.biHeight = rcClip.bottom - rcClip.top;
  710.       }
  711.  
  712.       /* Initialise printer stuff */
  713.       if (!(hDC = GetPrinterDC()))
  714.          break;
  715.       xSize = GetDeviceCaps(hDC, HORZRES);
  716.       ySize = GetDeviceCaps(hDC, VERTRES);
  717.       xRes = GetDeviceCaps(hDC, LOGPIXELSX);
  718.       yRes = GetDeviceCaps(hDC, LOGPIXELSY);
  719.  
  720.       /* Use half inch margins on left and right
  721.        * and one inch on top. Maintain the same aspect ratio.
  722.        */
  723.       dx = xSize - xRes;
  724.       dy = (int)((long)dx * bi.biHeight / bi.biWidth);
  725.  
  726.       /* Fix bounding rectangle for the picture .. */
  727.       Rect.top = yRes;
  728.       Rect.left = xRes / 2;
  729.       Rect.bottom = yRes + dy;
  730.       Rect.right = xRes / 2 + dx;
  731.  
  732.       /* ... and inform the driver */
  733.       Escape(hDC, SET_BOUNDS, sizeof(RECT), (LPSTR)&Rect, NULL);
  734.       bSave = TRUE;
  735.       if (InitPrinting(hDC, hWnd, hInst, Name))
  736.       {
  737.          PrintDIB(hWnd, hDC, xRes / 2, yRes, dx, dy);
  738.  
  739.          /* Signal to the driver to begin translating the drawing
  740.           * commands to printer output...
  741.           */
  742.          Escape(hDC, NEWFRAME, NULL, NULL, NULL);
  743.          TermPrinting(hDC);
  744.       }
  745.       DeleteDC(hDC);
  746.       break;
  747.  
  748.    case IDM_OPEN:
  749.       /* Bring up File/Open ... dialog */
  750.       ofn.lStructSize = sizeof(OPENFILENAME);
  751.       ofn.hwndOwner = hWnd;
  752.       ofn.hInstance = hInst;
  753.       ofn.lpstrFilter = szBitmapExt;
  754.       ofn.lpstrCustomFilter = NULL;
  755.       ofn.nMaxCustFilter = 0L;
  756.       ofn.nFilterIndex = 1L;
  757.       ofn.lpstrFile = (LPSTR)achFileName;
  758.       ofn.nMaxFile = 128;
  759.       ofn.lpstrInitialDir = NULL;
  760.       ofn.lpstrTitle = NULL;
  761.       ofn.lpstrFileTitle = NULL;
  762.       ofn.lpstrDefExt = NULL;
  763.       ofn.Flags = 0;
  764.       fh = GetOpenFileName((LPOPENFILENAME)&ofn);
  765.  
  766.       /*  Load up the DIB if the user did not press cancel */
  767.       if (fh > 0)
  768.       {
  769.          StartWait();
  770.          if (InitDIB(hWnd))
  771.             InvalidateRect(hWnd, NULL, FALSE);
  772.          else
  773.             bLegitDraw = FALSE;
  774.          EndWait();
  775.       }
  776.       break;
  777.  
  778.    case IDM_SAVE:
  779.       DibInfo(hbiCurrent, &bi);
  780.       fFileOptions = 0;
  781.  
  782.       /* Depending on compression type for current DIB,
  783.        * set the appropriate bit in the fFileOptions flag
  784.        */
  785.       if (bi.biCompression == BI_RGB)
  786.          fFileOptions |= F_RGB;
  787.       else if (bi.biCompression == BI_RLE4)
  788.          fFileOptions |= F_RLE4;
  789.       else if (bi.biCompression == BI_RLE8)
  790.          fFileOptions |= F_RLE8;
  791.  
  792.       /* Depending on bits/pixel type for current DIB,
  793.        * set the appropriate bit in the fFileOptions flag
  794.        */
  795.       switch (bi.biBitCount)
  796.          {
  797.       case 1:
  798.          fFileOptions |= F_1BPP;
  799.          break;
  800.  
  801.       case 4:
  802.          fFileOptions |= F_4BPP;
  803.          break;
  804.  
  805.       case 8:
  806.          fFileOptions |= F_8BPP;
  807.          break;
  808.  
  809.       case 24:
  810.          fFileOptions |= F_24BPP;
  811.          }
  812.  
  813.       /* Bring up File/Save... dialog and get info. about filename,
  814.        * compression, and bits/pix. of DIB to be written.
  815.        */
  816.       ofn.lStructSize = sizeof(OPENFILENAME);
  817.       ofn.hwndOwner = hWnd;
  818.       ofn.hInstance = hInst;
  819.       ofn.lpstrFilter = szBitmapExt;
  820.       ofn.lpstrCustomFilter = NULL;
  821.       ofn.nMaxCustFilter = 0;
  822.       ofn.nFilterIndex = 1;
  823.       ofn.lpstrFile = (LPSTR)achFileName;
  824.       ofn.nMaxFile = 128;
  825.       ofn.lpstrFileTitle = NULL;
  826.       ofn.nMaxFileTitle = 0;
  827.       ofn.lpstrInitialDir = NULL;
  828.       ofn.lpstrTitle = NULL;
  829.       ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  830.       ofn.nFileOffset = 0;
  831.       ofn.nFileExtension = 0;
  832.       ofn.lpstrDefExt = (LPSTR)"";
  833.       ofn.lCustData = 0L;
  834.       ofn.lpfnHook = NULL;
  835.       ofn.lpTemplateName = NULL;
  836.       fh = GetSaveFileName(&ofn);
  837.    /*   if (GetSaveFileName(&ofn))
  838.         {
  839.         OFSTRUCT of;
  840.         int cch;
  841.         char* pch;
  842.         HFILE hfile;
  843.         HLOCAL h;
  844.  
  845.         hfile = OpenFile(szFilename, &of, OF_CREATE | OF_WRITE);
  846.  
  847.         if (hfile != HFILE_ERROR)
  848.         {
  849.         h = Edit_GetHandle(hwndClient);
  850.         cch = Edit_GetTextLength(hwndClient);
  851.         pch = LocalLock(h);
  852.         if ((int)_lwrite(hfile, pch, cch) == cch)
  853.         fSuccess = TRUE;
  854.  
  855.         LocalUnlock(h);
  856.         _lclose(hfile);
  857.         }
  858.         }*/
  859.  
  860.  
  861.  
  862.  
  863.    /* Extract DIB specs. if the user did not press cancel */
  864.       if (fh != 0)
  865.       {
  866.          if (fFileOptions & F_RGB)
  867.             bi.biCompression = BI_RGB;
  868.          if (fFileOptions & F_RLE4)
  869.             bi.biCompression = BI_RLE4;
  870.          if (fFileOptions & F_RLE8)
  871.             bi.biCompression = BI_RLE8;
  872.          if (fFileOptions & F_1BPP)
  873.             bi.biBitCount = 1;
  874.          if (fFileOptions & F_4BPP)
  875.             bi.biBitCount = 4;
  876.          if (fFileOptions & F_8BPP)
  877.             bi.biBitCount = 8;
  878.          if (fFileOptions & F_24BPP)
  879.             bi.biBitCount = 24;
  880.  
  881.          /* Realize a DIB in the specified format and obtain a
  882.           * handle to it.
  883.           */
  884.          hdibCurrent = RealizeDibFormat(bi.biCompression, bi.biBitCount);
  885.          if (!hdibCurrent)
  886.          {
  887.             ErrMsg("Unable to save the specified file");
  888.             return 0L;
  889.          }
  890.  
  891.          /* Write the DIB */
  892.          StartWait();
  893.          if (!WriteDIB(achFileName, hdibCurrent))
  894.             ErrMsg("Unable to save the specified file");
  895.          EndWait();
  896.       }
  897.       break;
  898.  
  899.    case IDM_EXIT:
  900.       PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
  901.       break;
  902.  
  903.    case IDM_UPDATECOL:
  904.       /* Toggle state of "update screen colors" flag. If it is
  905.        * off, clear the "hide changes" flag
  906.        */
  907.       bUpdateColors = !bUpdateColors;
  908.       if (bUpdateColors)
  909.          bNoUgly = 0;
  910.       break;
  911.  
  912.    case IDM_DIBSCREEN:
  913.       bDIBToDevice = !bDIBToDevice;
  914.       InvalidateRect(hWnd, (LPRECT)(NULL), 1);
  915.       break;
  916.  
  917.    case IDM_MEMORYDIB:
  918.       bMemoryDIB = !bMemoryDIB;
  919.       break;
  920.  
  921.    case IDM_NOUGLY:
  922.       /* Toggle state of "hide changes" flag. If it is off, clear
  923.        * the "update screen colors" flag. This will tell SHOWDIB
  924.        * to paint itself black while the palette is changing.
  925.        */
  926.       bNoUgly = !bNoUgly;
  927.       if (bNoUgly)
  928.          bUpdateColors = 0;
  929.       break;
  930.  
  931.    case IDM_TRANSPARENT:
  932.       /* Toggle DC mode */
  933.       wTransparent = wTransparent == TRANSPARENT ? OPAQUE : TRANSPARENT;
  934.       break;
  935.  
  936.    case IDM_ANIMATE0:
  937.       if (!hpalSave)
  938.          break;
  939.  
  940.       /* Reset animation count and stop timer */
  941.       KillTimer(hWnd, 1);
  942.       nAnimating = 0;
  943.  
  944.       /* Restore palette which existed before animation started */
  945.       DeleteObject(hpalCurrent);
  946.       hpalCurrent = hpalSave;
  947.  
  948.       /* Rebuild bitmap based on newly realized information */
  949.       hDC = GetDC(hWnd);
  950.       SelectPalette(hDC, hpalCurrent, 0);
  951.       RealizePalette(hDC);
  952.       ReleaseDC(hWnd, hDC);
  953.       if (hbmCurrent)
  954.       {
  955.          DeleteObject(hbmCurrent);
  956.          hbmCurrent = NULL;
  957.          if (hdibCurrent)
  958.             hbmCurrent = BitmapFromDib(hdibCurrent, hpalCurrent);
  959.       }
  960.       hpalSave = NULL;
  961.  
  962.       /* Force redraw with new palette for everyone */
  963.       InvalidateRect(hWnd, NULL, TRUE);
  964.       break;
  965.  
  966.    case IDM_STEALCOL:
  967.  
  968.    case IDM_ANIMATE5:
  969.  
  970.    case IDM_ANIMATE20:
  971.  
  972.    case IDM_ANIMATE50:
  973.  
  974.    case IDM_ANIMATE100:
  975.  
  976.    case IDM_ANIMATE200:
  977.  
  978.    case IDM_ANIMATE201:
  979.       /* Set animation count i.e number of times animation is to
  980.        * take place.
  981.        */
  982.       nAnimating = id;
  983.       if (id == IDM_STEALCOL)
  984.          nAnimating = 0;
  985.  
  986.       /* Save current palette */
  987.       hpalSave = CopyPalette(hpalCurrent);
  988.       GetObject(hpalCurrent, sizeof(int), (LPSTR)&pLogPal->palNumEntries);
  989.       GetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->
  990.                         palPalEntry);
  991.  
  992.       /* Reserve all entries in the palette otherwise AnimatePalette()
  993.        * will not modify them
  994.        */
  995.       for (i = 0; i < pLogPal->palNumEntries; i++)
  996.       {
  997.          pLogPal->palPalEntry[i].peFlags = (BYTE)PC_RESERVED;
  998.       }
  999.       SetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->
  1000.                         palPalEntry);
  1001.  
  1002.       /* Rebuild bitmap based on newly realized information */
  1003.       if (hbmCurrent)
  1004.       {
  1005.          DeleteObject(hbmCurrent);
  1006.          hbmCurrent = NULL;
  1007.          if (hdibCurrent)
  1008.             hbmCurrent = BitmapFromDib(hdibCurrent, hpalCurrent);
  1009.       }
  1010.  
  1011.       /* Force redraw with new palette for everyone */
  1012.       InvalidateRect(hWnd, NULL, TRUE);
  1013.  
  1014.       /* Initiate the timer so that palette can be animated in
  1015.        * response to a WM_TIMER message
  1016.        */
  1017.       if ((UINT)nAnimating && !SetTimer(hWnd, (UINT)1, (UINT)250, (TIMERPROC)
  1018.                                         NULL))
  1019.          nAnimating = 0;
  1020.  
  1021.    default:
  1022.       break;
  1023.       }
  1024.    return TRUE;
  1025. }
  1026.  
  1027. /****************************************************************************
  1028.  *                                                                          *
  1029.  *  FUNCTION   : InitDIB(hWnd)                                              *
  1030.  *                                                                          *
  1031.  *  PURPOSE    : Reads a DIB from a file, obtains a handle to it's          *
  1032.  *               BITMAPINFO struct., sets up the palette and loads the DIB. *
  1033.  *                                                                          *
  1034.  *  RETURNS    : TRUE  - DIB loads ok                                       *
  1035.  *               FALSE - otherwise                                          *
  1036.  *                                                                          *
  1037.  ****************************************************************************/
  1038.  
  1039.  
  1040. int InitDIB (hWnd)
  1041. HWND hWnd;
  1042. {
  1043.    unsigned fh;
  1044.    LPBITMAPINFOHEADER lpbi;
  1045.    WORD FAR *pw;
  1046.    int i;
  1047.    BITMAPINFOHEADER bi;
  1048.    OFSTRUCT of;
  1049.  
  1050.    FreeDib();
  1051.  
  1052.    /* Open the file and get a handle to it's BITMAPINFO */
  1053.    fh = OpenFile(achFileName, (LPOFSTRUCT)&of, OF_READ);
  1054.    if (fh == -1)
  1055.    {
  1056.       ErrMsg("Can't open file '%ls'", (LPSTR)achFileName);
  1057.       return FALSE;
  1058.    }
  1059.    hbiCurrent = ReadDibBitmapInfo(fh);
  1060.    dwOffset = _llseek(fh, 0L, SEEK_CUR);
  1061.    _lclose(fh);
  1062.    if (hbiCurrent == NULL)
  1063.    {
  1064.       ErrMsg("%ls is not a Legitimate DIB File!", (LPSTR)achFileName);
  1065.       return FALSE;
  1066.    }
  1067.    DibInfo(hbiCurrent, &bi);
  1068.  
  1069.    /* Set up the palette */
  1070.    hpalCurrent = CreateDibPalette(hbiCurrent);
  1071.    if (hpalCurrent == NULL)
  1072.    {
  1073.       ErrMsg("CreatePalette() Failed");
  1074.       return FALSE;
  1075.    }
  1076.  
  1077.    /*  Convert the DIB color table to palette relative indexes, so
  1078.     *  SetDIBits() and SetDIBitsToDevice() can avoid color matching.
  1079.     *  We can do this because the palette we realize is identical
  1080.     *  to the color table of the bitmap, ie the indexes match 1 to 1
  1081.     *
  1082.     *  Now that the DIB color table is palette indexes not RGB values
  1083.     *  we must use DIB_PAL_COLORS as the wUsage parameter to SetDIBits()
  1084.     */
  1085.    lpbi = (VOID FAR *)GlobalLock(hbiCurrent);
  1086.    if (lpbi->biBitCount != 24)
  1087.    {
  1088.       fPalColors = TRUE;
  1089.       pw = (WORD FAR *)((LPSTR)lpbi + lpbi->biSize);
  1090.       for (i = 0; i < (int)lpbi->biClrUsed; i++)
  1091.          *pw++ = (WORD)i;
  1092.    }
  1093.    GlobalUnlock(hbiCurrent);
  1094.    bLegitDraw = TRUE;
  1095.  
  1096.    /*  If the input bitmap is not in RGB FORMAT the banding code will
  1097.     *  not work!  we need to load the DIB bits into memory.
  1098.     *  if memory DIB, load it all NOW!  This will avoid calling the
  1099.     *  banding code.
  1100.     */
  1101.    if (bMemoryDIB || bi.biCompression != BI_RGB)
  1102.       hdibCurrent = OpenDIB(achFileName);
  1103.  
  1104.    /*  If the RLE could not be loaded all at once, exit gracefully NOW,
  1105.     *  to avoid calling the banding code
  1106.     */
  1107.    if ((bi.biCompression != BI_RGB) && !hdibCurrent)
  1108.    {
  1109.       ErrMsg("Could not load RLE!");
  1110.       FreeDib();
  1111.       return FALSE;
  1112.    }
  1113.    if (hdibCurrent && !bDIBToDevice && bMemoryDIB)
  1114.    {
  1115.       hbmCurrent = BitmapFromDib(hdibCurrent, hpalCurrent);
  1116.       if (!hbmCurrent)
  1117.       {
  1118.          ErrMsg("Could not create bitmap!");
  1119.          FreeDib();
  1120.          return FALSE;
  1121.       }
  1122.    }
  1123.    SizeWindow(hWnd);
  1124.    return TRUE;
  1125. }
  1126. /****************************************************************************
  1127.  *                                                                          *
  1128.  *  FUNCTION   : FreeDib(void)                                              *
  1129.  *                                                                          *
  1130.  *  PURPOSE    : Frees all currently active bitmap, DIB and palette objects *
  1131.  *               and initializes their handles.                             *
  1132.  *                                                                          *
  1133.  ****************************************************************************/
  1134.  
  1135.  
  1136. void FreeDib (void)
  1137. {
  1138.    if (hpalCurrent)
  1139.       DeleteObject(hpalCurrent);
  1140.    if (hbmCurrent)
  1141.       DeleteObject(hbmCurrent);
  1142.    if (hdibCurrent)
  1143.       GlobalFree(hdibCurrent);
  1144.    if (hbiCurrent && hbiCurrent != hdibCurrent)
  1145.       GlobalFree(hbiCurrent);
  1146.    fPalColors = FALSE;
  1147.    bLegitDraw = FALSE;
  1148.    hpalCurrent = NULL;
  1149.    hdibCurrent = NULL;
  1150.    hbmCurrent = NULL;
  1151.    hbiCurrent = NULL;
  1152.    SetRectEmpty(&rcClip);
  1153. }
  1154.